
import React from 'react';
import * as THREE from 'three';
import { ToolType } from '../constants/ToolType';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls';
import Controller from "../Controller";

/** 原件控制器 */
export default function useTransformControls(controller: Controller) {

    /** 摄像机 */
    const camera = controller.useMemo(s => s.camera, [])

    /** 渲染器 */
    const renderer = controller.useMemo(s => s.renderer, [])

    /** 场景 */
    const scene = controller.useMemo(s => s.scene, []);

    /** 选中原件的UUID */
    const selectedElementUuid = controller.useMemo(s => s.selectedElementUuid, []);

    /** 原件控制器 */
    const transformControls = React.useRef<TransformControls>();

    /** 原件字典 */
    const elementMap = controller.useMemo(s => s.elementMap, []);

    /** 选中的原件 */
    const selectedElement = React.useMemo(() => selectedElementUuid && elementMap.get(selectedElementUuid), [elementMap, selectedElementUuid])

    /** 选中得工具 */
    const selectedTool = controller.useMemo(s => s.selectedTool, []);

    const object3D = React.useMemo(() => {
        if (!selectedElement) return;
        if (selectedElement.object3D instanceof THREE.Object3D) {
            return selectedElement.object3D
        } else {
            return selectedElement.object3D.scene.scene as THREE.Object3D
        }
    }, [selectedElement])

    // 切换工具
    React.useEffect(() => {
        if (!camera || !renderer || !scene || !object3D) return;

        transformControls.current = new TransformControls(camera, renderer.domElement);

        if (selectedTool === ToolType.移动 && selectedElement) {
            transformControls.current.attach(object3D).setMode("translate");
            scene.add(transformControls.current);
        } else if (selectedTool === ToolType.旋转 && selectedElement) {
            transformControls.current.attach(object3D).setMode("rotate");
            scene.add(transformControls.current);
        } else if (selectedTool === ToolType.形变 && selectedElement) {
            transformControls.current.attach(object3D).setMode("scale");
            scene.add(transformControls.current);
        } else {
            scene.remove(transformControls.current.detach());
        }

        return () => {
            if (!transformControls.current) return;
            scene.remove(transformControls.current.detach());
        }
    }, [camera, object3D, renderer, scene, selectedElement, selectedTool])
}